home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ADA Programming Guide
/
ADA Programming Guide.iso
/
ada_gwu
/
gutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-30
|
15KB
|
638 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#define GEN
#include "hdr.h"
#include "vars.h"
#include "segment.h"
#include "gvars.h"
#include "setp.h"
#include "segmentp.h"
#include "dbxp.h"
#include "miscp.h"
#include "gmiscp.h"
#include "smiscp.h"
#include "gutilp.h"
static short nature_root_type(Symbol);
extern Tuple segment_map_new(), segment_map_put();
extern Segment segment_map_get();
extern Segment CODE_SEGMENT, DATA_SEGMENT, DATA_SEGMENT_MAIN;
/* create dummy entry for p (np is string with name of p)
* and call chaos if p is called
*/
#define undone(p, np) p() { chaos(strjoin(np, " not implemented")); }
int ada_bool(int x) /*;ada_bool*/
{
return (x != 0 ? 1 : 0) ;
}
int assoc_symbol_exists(Symbol sym, int aname) /*;assoc_symbol_exists*/
{
/* return TRUE if assoc_symbol_get would succeed, FALSE otherwise */
Tuple tup;
tup = ASSOCIATED_SYMBOLS(sym);
if (tup == (Tuple)0)
return FALSE;
else
return (tup[aname] != (char *)0);
}
Symbol assoc_symbol_get(Symbol sym, int aname) /*;assoc_symbol_get*/
{
/* Enter asym as associated symbol of symbol sym. Aname is code
* definining position in tuple of associated symbols. The tuple
* is allocated if not already defined
*/
Tuple tup;
tup = ASSOCIATED_SYMBOLS(sym);
if (tup == (Tuple)0) /* if not allocated*/
chaos("assoc_symbol_get: tuple not allocated");
if (tup_size(tup)<aname)
chaos("associate_symbol_get: index out of range");
if (tup[aname] == (char *)0)
chaos("assoc_symbol_get: symbol not present");
return (Symbol) tup[aname];
}
void assoc_symbol_put(Symbol sym, int aname, Symbol asym) /*;assoc_symbol_put*/
{
/* Enter asym as associated symbol of symbol sym. Aname is code
* definining position in tuple of associated symbols. The tuple
* is allocated if not already defined
*/
Tuple tup;
tup = ASSOCIATED_SYMBOLS(sym);
if (tup == (Tuple)0) { /* if need new tuple */
/* allocate three entries for now, should allocate proper count later */
tup = tup_new(3);
tup[1] = (char *)0;
tup[2] = (char *)0;
tup[3] = (char *)0;
}
if (tup_size(tup) < aname)
chaos("associate_symbol_put: index out of range");
tup[aname] = (char *) asym;
ASSOCIATED_SYMBOLS(sym) = tup;
}
#ifdef DEBUG
/* Calls to COMPILER_ERROR in SETL are translated to calls to
* commpiler_error in C. Where the SETL version builds up a string
* the C version adds a suffix to indicate argument type. For example
* compiler_error_n(s, n) to pass node. The case compiler_error_k is
* used to pass node for which the SETL version has
* COMPILER_ERROR(s + str N_KIND(node)
* This is written in C as
* compiler_error_k(s, node)
* These are defined for DEBUG (base) version only. In the export version,
* they are redefined as macros (in ghdr.c) to call procedure
* exit_internal_error().
*/
void compiler_error_k(char *s, Node node) /*;compiler_error_k*/
{
printf("compiler error: %s\n", s);
zpnod(node);
errors++;
chaos("compiler_error_k");
}
void compiler_error_c(char *s, Tuple t) /*;compiler_error_c*/
{
/* second arg is tuple corresponding to constraint*/
printf("compiler_error_c: %s\n", s);
errors++;
chaos("compile_error_c");
}
void compiler_error_s(char *s, Symbol sym) /*;compiler_error_s*/
{
/* second argument is symbol */
printf("compiler_error_s: %s\n", s);
zpsym(sym);
errors++;
chaos("compiler_error_s");
}
#endif
Tuple discriminant_list_get(Symbol record) /*;discriminant_list_get*/
{
/* DISCRIMINANT_LIST(record); SIGNATURE(root_type(record))(2) */
Tuple tup;
tup = SIGNATURE(root_type(record));
return (Tuple) tup[3];
}
/* The SETL map EMAP is accessed in C by the following procedures:
* emap_get(symbol)
* emap_put(symbol, value)
* Note that emap_get returns TRUE if EMAP defined for the argument,
* and sets EMAP_VALUE to the value, or returns FALSE if the value
* not defined.
* The SETL sequence
* EMAP(s) = OM;
* is translated as
* emap_undef(s);
*/
int emap_get(Symbol sym) /*;emap_get*/
{
int i, n;
n = tup_size(EMAP);
for (i = 1; i <= n; i += 2) {
if (EMAP[i] == (char *) sym) {
EMAP_VALUE = (Tuple) EMAP[i+1];
return TRUE;
}
}
return FALSE;
}
void emap_put(Symbol sym, char *val) /*;emap_put*/
{
int i, n;
n = tup_size(EMAP);
for (i = 1; i <= n; i += 2) {
if (EMAP[i] == (char *) sym) {
EMAP[i+1] = val;
return;
}
}
EMAP = tup_with(EMAP, (char *) sym); /* add as new entry */
EMAP = tup_with(EMAP, (char *) val); /* add new value */
}
void emap_undef(Symbol s) /*;emap_undef*/
{
int i, n, j;
n = tup_size(EMAP);
for (i = 1; i <= n; i += 2) {
if (EMAP[i] == (char *) s) {
/* if defined here, move down later entries*/
for (j = i; j < n - 1; j ++) {
EMAP[j] = EMAP[j+2];
}
}
}
}
void generate_object(Symbol s) /*;generate_object*/
{
if (!tup_mem((char *)s, GENERATED_OBJECTS))
GENERATED_OBJECTS = tup_with(GENERATED_OBJECTS, (char *) s);
}
Tuple get_constraint(Symbol type_name) /*;get_constraint*/
{
/* constraints on access types are now also tuples in the C version.*/
if (is_array(type_name) || NATURE(base_type(type_name)) == na_subtype) {
Tuple tup; /* TBSL: make this a static constant */
tup = tup_new(5);
tup[1] = (char *)co_index;
tup[2] = (char *)OPT_NODE;
tup[3] = (char *)OPT_NODE;
return tup;
}
else {
return SIGNATURE(type_name);
}
}
Symbol get_type(Node node) /*;get_type*/
{
int nk;
Symbol sym;
nk = N_KIND(node);
if (nk == as_simple_name || nk == as_subtype_indic) {
sym = N_UNQ(node);
if (sym == (Symbol)0) {
#ifdef DEBUG
zpnod(node);
#endif
chaos("get_type: N_UNQ not defined for node");
}
else {
sym = TYPE_OF(sym);
}
}
else {
sym = N_TYPE(node);
}
return sym;
}
int has_discriminant(Symbol typ) /*;has_discriminant*/
{
/* Note that has_discriminant is adasem macro that is NOT same as
* discriminant_list macro defined in adagen. Calls of the latter must
* be translated as discriminant_list_get.
*/
Tuple tup;
tup = discriminant_list_get(typ);
if (tup == (Tuple)0) return FALSE;
return tup_size(tup) > 0;
}
int has_static_size(Symbol typ) /*;has_static_size*/
{
return size_of(typ) >= 0;
}
int is_access_type(Symbol typ) /*;is_access_type*/
{
return nature_root_type(typ) == na_access;
}
int is_aggregate(Node node) /*;is_aggregate*/
{
register int nk;
nk = N_KIND(node);
return nk == as_array_aggregate || nk == as_array_ivalue
|| nk == as_record_aggregate || nk == as_record_ivalue;
}
int is_array_type(Symbol typ) /*;is_array_type*/
{
return nature_root_type(typ) == na_array;
}
int is_entry_type(Symbol typ) /*;is_entry_type*/
{
return NATURE(typ) == na_entry_former;
}
int is_enumeration_type(Symbol typ) /*;is_enumeration_type*/
{
return NATURE(root_type(typ)) == na_enum;
}
int is_float_type(Symbol typ) /*;is_float_type*/
{
Tuple tup;
tup = SIGNATURE(typ);
return (int)tup[1] == co_digits;
}
int is_formal_parameter(Symbol sym) /*;is_formal_parameter*/
{
register int na;
int s_n, found;
Symbol same_sym, sym_scope;
Fortup ft1;
na = NATURE(sym);
return ((na == na_in || na == na_inout || na == na_out)
&& assoc_symbol_exists(sym,FORMAL_TEMPLATE) );
}
int is_global(Symbol sym) /*;is_global*/
{
return sym->s_segment != -1;
}
int is_integer_type(Symbol typ) /*;is_integer_type*/
{
return root_type(typ) == symbol_integer;
}
int is_ivalue(Node node) /*;is_ivalue*/
{
int nk = N_KIND(node);
return nk == as_ivalue || nk == as_int_literal || nk == as_string_ivalue
|| nk == as_real_literal || nk == as_array_ivalue
|| nk == as_record_ivalue;
}
int is_object(Node node) /*;is_object*/
{
int nk = N_KIND(node);
return nk == as_simple_name || nk == as_null || nk == as_name
|| nk == as_slice || nk == as_index || nk == as_selector;
}
int is_record_subtype(Symbol typ) /*;is_record_subtype*/
{
return is_record_type(typ) && NATURE(typ) == na_subtype;
}
int is_record_type(Symbol typ) /*;is_record_type*/
{
return nature_root_type(typ) == na_record;
}
int is_renaming(Symbol sym) /*;is_renaming*/
{
return ALIAS(sym) != (Symbol)0;
}
int is_simple_name(Node node) /*;is_simple_name*/
{
int nk = N_KIND(node);
return nk == as_simple_name || nk == as_null || nk == as_name;
}
int is_simple_type(Symbol typ) /*;is_simple_type*/
{
return nature_root_type(typ) != na_array
&& nature_root_type(typ) != na_record;
}
int is_static_type(Symbol typ) /*;is_static_type*/
{
return is_global(typ) && has_static_size(typ);
}
int local_reference_map_defined(Symbol sym) /*;local_reference_map_defined*/
{
/* return TRUE if local_reference_map defined for sym, else FALSE */
int i, n;
n = tup_size(LOCAL_REFERENCE_MAP);
for (i = 1; i <= n; i += 2) {
if (LOCAL_REFERENCE_MAP[i] == (char *) sym)
return TRUE;
}
return FALSE;
}
Tuple local_reference_map_new() /*;local_reference_map_new*/
{
return tup_new(0);
}
unsigned int local_reference_map_get(Symbol sym) /*;local_reference_map_get*/
{
int i, n;
n = tup_size(LOCAL_REFERENCE_MAP);
for (i = 1; i <= n; i += 2) {
if (LOCAL_REFERENCE_MAP[i] == (char *) sym)
return (unsigned int) LOCAL_REFERENCE_MAP[i+1];
}
chaos("local_reference_map_get unable to find value ");
return 0;
}
void local_reference_map_put(Symbol sym, int off) /*;local_reference_map_put*/
{
int i, n;
n = tup_size(LOCAL_REFERENCE_MAP);
for (i = 1; i <= n; i += 2) {
if (LOCAL_REFERENCE_MAP[i] == (char *)sym) {
LOCAL_REFERENCE_MAP[i+1] = (char *) off;
return;
}
}
LOCAL_REFERENCE_MAP = tup_exp(LOCAL_REFERENCE_MAP, n+2);
LOCAL_REFERENCE_MAP[n+1] = (char *) sym;
LOCAL_REFERENCE_MAP[n+2] = (char *) off;
}
int mu_size(int mutyp) /*;mu_size*/
{
/* This procedure returns the number of storage units required for
* the memory type given by mutyp, one of the mu_ codes.
*/
#ifdef WORDSIZE16
switch (mutyp) {
case(mu_byte):
case(mu_word):
return 1;
case(mu_addr):
case(mu_long):
case(mu_xlng): /* check that mu_xlng value right */
return 2; /* check desired size */
case(mu_dble):
return 4;
default:
chaos("mu_size: bad argument");
return 0;
}
#else
switch (mutyp) {
case(mu_byte):
case(mu_word):
case(mu_long):
return 1;
case(mu_addr):
case(mu_xlng): /* check that mu_xlng value right */
return 2; /* check desired size */
case(mu_dble):
return 4;
default:
chaos("mu_size: bad argument");
return 0;
}
#endif
}
int su_size(int ktyp) /*;su_size*/
{
/* This procedure returns the number of storage units required for
* the memory type given by ktyp, one of the TK_ codes.
*/
#ifdef WORDSIZE16
switch (ktyp) {
case TK_BYTE:
case TK_WORD:
return 1;
case TK_LONG:
case TK_XLNG:
case TK_ADDR:
return 2;
case TK_DBLE:
return 4;
default:
chaos("su_size: bad argument");
return 0; /* for the sake of lint */
}
#else
switch (ktyp) {
case TK_BYTE:
case TK_LONG:
case TK_WORD:
return 1;
case TK_XLNG:
case TK_ADDR:
return 2;
case TK_DBLE:
return 4;/* dble is double address, not C double */
default:
chaos("su_size: bad argument");
return 0; /* for the sake of lint */
}
#endif
}
void next_local_reference(Symbol name) /*;next_local_reference*/
{
LAST_OFFSET -= mu_size(mu_addr);
local_reference_map_put(name, LAST_OFFSET);
}
void next_global_reference_def(Symbol name) /*;next_global_reference_def*/
{
/* begin definition of initial data for specified symbol at end
* of currrent data segment.
*/
#ifdef MACHINE_CODE
Gref gref;
#endif
S_SEGMENT(name) = CURRENT_DATA_SEGMENT;
S_OFFSET(name) = DATA_SEGMENT->seg_maxpos;
/*REFERENCE_MAP(name) = [CURRENT_DATA_SEGMENT, #DATA_SEGMENT+1];*/
#ifdef MACHINE_CODE
if (list_code) { /* save for printout */
gref = (Gref) emalloct(sizeof(Gref_s), "gref");
gref->gref_sym = name;
gref->gref_seg = CURRENT_DATA_SEGMENT;
gref->gref_off = DATA_SEGMENT->seg_maxpos;
/*n = tup_size(global_reference_tuple);*/
global_reference_tuple = tup_with(global_reference_tuple, (char *)gref);
}
#endif
}
void next_global_reference_r(Symbol sym, int seg, unsigned int off)
/*;next_global_reference_r*/
{
/* need to extend DATA_SEGMENT with seg and off */
next_global_reference_def(sym);
segment_put_word(DATA_SEGMENT, seg);
segment_put_word(DATA_SEGMENT, off);
}
void next_global_reference_segment(Symbol sym, Segment seg)
/*;next_global_reference_segment*/
{
/* install segment seg as next global reference */
next_global_reference_def(sym);
segment_append(DATA_SEGMENT, seg);
}
void next_global_reference_template(Symbol sym, Segment seg)
/*;next_global_reference_template*/
{
next_global_reference_segment(sym, seg);
}
void next_global_reference_z(Symbol sym) /*;next_global_reference_z*/
{
/* This corresponds to SETL case next_global_reference(sym, [0, 0]);]
* which we translate to next_global_reference_r for now, though
* the correctness of this translation needs to be checked
*/
next_global_reference_def(sym);
segment_put_word(DATA_SEGMENT, 0);
segment_put_word(DATA_SEGMENT, 0);
}
void next_global_reference_word(Symbol sym, int w)
/*;next_global_reference_word*/
{
/* This corresponds to SETL case of adding value [n] where n is assumed
* to take only a word.
*/
next_global_reference_def(sym);
segment_put_word(DATA_SEGMENT, w);
}
Symbol new_unique_name(char *s) /*;new_unique_name*/
{
/* TBSL: see if this is right translation? ds 3-12-85 */
/* If list_code on, then create ORIG_NAME from argument by appending
* sequence number
*/
#ifdef MACHINE_CODE
Symbol sym;
char seq[10];
sym = sym_new(na_void);
sprintf(seq, "#%d", S_SEQ(sym));
ORIG_NAME(sym) = (s != (char *)0) ? strjoin(s, seq) : strjoin(seq, "");
return sym;
#else
return sym_new(na_void);
#endif
}
static short nature_root_type(Symbol typ) /*;nature_root_type*/
{
Symbol sym;
if (typ == (Symbol)0)
chaos("gutil.c : nature_root_type argument null");
sym = root_type(typ);
if (sym == (Symbol)0)
chaos("gutil.c : nature_root_type, root_type of arg null");
return NATURE(sym);
}
Segment segment_map_get(Tuple tup, int sn) /*;segment_map_get*/
{
/* tup is segment map, sn is segment number */
int i, n;
n = tup_size(tup);
for (i = 1; i<n; i += 2) {
if ((int) tup[i] == sn)
return (Segment) tup[i+1];
}
return (Segment) 0;
}
Tuple segment_map_put(Tuple tup, int sn, Segment seg) /*;segment_map_put*/
{
/* tup is segment map, sn is segment number */
int i, n;
n = tup_size(tup);
for (i = 1; i<n; i += 2) {
if ((int) tup[i] == sn) {
tup[i+1] = (char *) seg;
return tup;
}
}
/* here if no entry, make new one, possible reallocating tuple */
tup = tup_exp(tup, n+2);
tup[n+1] = (char *) sn;
tup[n+2] = (char *) seg;
return tup;
}
Const small_of(Symbol typ) /*;small_of*/
{
/* It returns const, that should always be rational and so
* perhaps should insert check here that this holds ds 7-1-85*/
Tuple tup = SIGNATURE(typ);
return get_ivalue((Node)tup[5]);
}